package com.pojoin.cms.dao.impl.hibernate;

import java.lang.reflect.ParameterizedType;
import java.sql.SQLException;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.dao.support.DataAccessUtils;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.pojoin.cms.dao.base.BaseDao;
import com.pojoin.cms.util.criteria.Criteria;
import com.pojoin.cms.util.criteria.orderby.Orderby;
import com.pojoin.cms.util.pager.Pager;
import com.pojoin.cms.util.pager.PagerChecker;

/**
 * 
 * @author pojoin
 *
 * @param <T>
 * 
 * @date 2010-09-22
 */
public abstract class BaseDaoHibernate<T> extends HibernateDaoSupport implements BaseDao<T>  {

	private Class<T> entityClass;
	
	/**
	 * 初始化
	 */
	@SuppressWarnings("unchecked")
	protected BaseDaoHibernate() {
		this.entityClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
	}
	
	/**
	 * 删除对象
	 * @param t
	 */
	@Override
	public void deleteObject(T t) {
		this.getHibernateTemplate().delete(t);
		
	}

	/**
	 * 根据id得到对象
	 * @param id
	 * @return
	 */
	@SuppressWarnings("unchecked")
	@Override
	public T getObjectById(Long id) {
		return (T) this.getHibernateTemplate().get(entityClass, id);
	}
	
	/**
	 * 更新对象
	 * @param t
	 * @return
	 */
	@Override
	public T updateObject(T t) {
		this.getHibernateTemplate().saveOrUpdate(t);
		T object=t;
		this.getHibernateTemplate().flush();
		return object;
	}

	/**
	 * 插入对象
	 * @param t
	 * @return
	 */
	@Override
	public T insertObject(T t) {
		this.getHibernateTemplate().save(t);
		return t;
	}

	/**
	 * 根据条件查询是否存在对象
	 * @param queryHQL
	 * @return
	 */
	@Override
	public boolean objectExist(final String queryHQL) {
		return (Boolean)this.getHibernateTemplate().execute(new HibernateCallback(){
			@Override
			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				Query query=session.createQuery(queryHQL);
				if(query.list().size()<=0){
					return false;
				}
				return true;
			}
		});
	}

	/**
	 * 根据条件进行查询对象列表，并进行升序或降序排序
	 * @param criteria 查询条件
	 * @param orderby 排序
	 * @param pageIndex 
	 * @param pageSize
	 * @return
	 */
	@SuppressWarnings("unchecked")
	@Override
	public List<T> queryPagerObjectListByCriteriaAndOrderby(Criteria criteria,
			Orderby orderby, int pageIndex, int pageSize) {
		String str="";
		if(criteria!=null){
			str=str+" where "+criteria.getSQLCriteria();
		}if(orderby!=null){
			str=str+orderby.getSQL();
		}
		if(pageIndex<=0 || pageSize<=0){
			return this.getHibernateTemplate().find(this.getBaseSql() + str);
		}else{
			return this.queryPagerObjectListByHQL(this.getBaseSql() + str, pageIndex, pageSize);	
		}
	}
	
	
	/**
	 * 根据条件查询
	 * @param criteria
	 * @param orderby 
	 * @return
	 */
	@SuppressWarnings("unchecked")
	protected List<T> queryObjectListByCriter(Criteria criteria, Orderby orderby){
		String hql = this.getBaseSql();
		if(criteria != null){
			hql += " where " + criteria.getSQLCriteria();
		}
		if(orderby != null){
			hql += " " + orderby.getSQL();
		}
		return this.getHibernateTemplate().find(hql);
	}

	/**
	 * 分页查询，根据HQL语句查询对象列表
	 * @param queryHQL
	 * @param pageIndex
	 * @param pageSize
	 * @return
	 */
	@SuppressWarnings("unchecked")
	@Override
	public List<T> queryPagerObjectListByHQL(final String queryHQL, final int pageIndex,
			final int pageSize) {
		Object o = this.getHibernateTemplate().execute(new HibernateCallback() {
			@Override
			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				Query query = session.createQuery(queryHQL);
				query.setMaxResults(pageSize);
				query.setFirstResult((pageIndex - 1) * pageSize);
				return query.list();
			}
		});
		List<T> list = (List<T>) o;
		return list;
	}

	/**
	 * 查询返回记录的总数量,返回int类型
	 * @param queryHQL
	 * @return
	 */
	@Override
	public int queryResultCount(String queryHQL) {
		return DataAccessUtils.intResult(getHibernateTemplate().find(queryHQL));
	}

	/**
	 * 根据HQL查询唯一对象，返回Object
	 * @param queryHQL
	 * @return
	 */
	@SuppressWarnings("unchecked")
	@Override
	public T queryUniqueObject(final String queryHQL) {
		T o = (T) this.getHibernateTemplate().execute(new HibernateCallback() {
			@Override
			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				Query query = session.createQuery(queryHQL);
				return query.uniqueResult();
			}
		});
		return o;
	}

	/**
	 * 基础sql
	 * @return
	 */
	abstract String getBaseSql();

	/**
	 * 根据条件进行查询对象列表，并进行升序或降序排序
	 * @param c
	 * @param orderby
	 * @param pager
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<T> queryPagerObjectListByCriteriaAndOrderby(
			Criteria criteria, Orderby orderby, Pager pager) {
		pager = PagerChecker.checkPageer(pager);
		String str=this.getBaseSql();
		if(criteria!=null){
			str=str+" where "+criteria.getSQLCriteria();
		}
		if(orderby!=null){
			str=str+ " " + orderby.getSQL();
		}
		
		pager.setResultCount(this.queryResultCount( "select count(id) " + str));
		if(pager.getPageNo()<=0 || pager.getPageSize()<=0){
			return this.getHibernateTemplate().find(str);
		}else{
			return this.queryPagerObjectListByHQL(str, pager.getPageNo(), pager.getPageSize());	
		}
	}

}
